<script setup lang="ts">
import {computed, reactive, ref, unref} from "vue";
import {ArrowDown, Check, Close} from "@element-plus/icons-vue";
import type {DropdownInstance, FormInstance} from "element-plus";
import {ftpStorage, serverStorage} from "@/storage";
import {ElMessage} from "element-plus";
import {findTree, generateUUID, toLinuxPath} from "@/utils";
import {defaultServerStorage} from "@/storage/defaults";

const dropdownRef = ref<DropdownInstance>()
const filename = ref('')
const write = ref('')
const formRef = ref<FormInstance>()
const dialogVisible = ref(false)
const form = reactive<WebType>({
  id: generateUUID(),
  title: '成都147MIS',
  ftp_id: 'test_1111',
  target: '/home/mis/www/',
  source: 'D:\\projects\\MisWWW\\vue-element-plus\\dist_mis',
  exclude: [],
  writes: [],
  filename: 'admin'
})

// const rules = reactive<FormRules>({
//   ftp_id: [{required: true, message: '请选择服务器', trigger: 'blur'}],
//   target: [{required: true, message: '请输入上传路径(上传的文件夹)', trigger: 'blur'}],
//   source: [{required: true, message: '请输入本地路径(本地的文件夹)', trigger: 'blur'}],
// })

const open = (row?: WebType) => {
  onEval(true, row)
  dialogVisible.value = true
}

/**
 * 赋值
 * @param isId 是否赋值id
 * @param row
 */
const onEval = (isId: boolean, row?: WebType) => {
  if (row) {
    if (isId) form.id = row.id
    form.title = row.title
    form.ftp_id = row.ftp_id
    form.target = row.target
    form.source = row.source
    form.filename = row.filename
    form.build = row.build
    form.appcmd = row.appcmd

    form.exclude = JSON.parse(JSON.stringify(row.exclude))
    form.writes = JSON.parse(JSON.stringify(row.writes))
    if (row.children) form.children = JSON.parse(JSON.stringify(row.children))
    else delete form.children
  } else {
    if (isId) form.id = ''
    form.title = ''
    form.ftp_id = ''
    form.target = ''
    form.source = ''
    form.filename = ''
    form.build = 'pnpm build'
    form.appcmd = ''
    form.exclude = []
    form.writes = []
    delete form.children
  }
}

const onSubmitForm = () => {
  if (form.id) {
    if (!form.title) form.title = form.target || '匿名'
    const item = findTree(unref(serverStorage), item => item.id === form.id)
    if (item) {
      const editForm: WebType = JSON.parse(JSON.stringify(form))
      // @ts-ignore
      for (const k in form) item[k] = editForm[k];
      ElMessage.success('编辑成功')
    }
  } else {
    if (!form.title) form.title = form.target || '匿名'
    form.id = generateUUID()
    serverStorage.value.push(JSON.parse(JSON.stringify(form)))
    ElMessage.success('新增成功')
  }
  dialogVisible.value = false
}

const onAddWrite = () => {
  const value = write.value.trim()
  if (value) {
    if (form.writes.includes(value)) {
      ElMessage.warning('命令已存在')
    } else {
      form.writes.push(write.value)
      write.value = ''
    }
  } else {
    ElMessage.warning('请输入命令')
  }
}

const onRemoveWrite = (index: number) => {
  form.writes.splice(index, 1)
}

const onAddExclude = () => {
  const value = filename.value.trim()
  if (value) {
    if (form.exclude.includes(value)) {
      ElMessage.warning('文件名称已存在')
    } else {
      form.exclude.push(filename.value)
      filename.value = ''
    }
  } else {
    ElMessage.warning('请输入文件名')
  }
}

const exportAddExclude = () => {
  const list = defaultServerStorage()
  form.exclude = list.length ? list[0].exclude : form.exclude
}

const onRemoveExclude = (index: number) => {
  form.exclude.splice(index, 1)
}

const onCommand = (data: WebType) => {
  if (!data.children || !data.children.length) {
    onEval(false, data)
    ElMessage.success('复制成功')
    dropdownRef.value?.handleClose()
  }
}

const onWriteCmd = (cmd: string) => {
  write.value = cmd

  if (form.filename) {
    write.value += form.filename
  }
}

const ftp = computed(() => {
  return findTree(unref(ftpStorage), item => item.id === form.ftp_id)
})

const targetLabel = computed(() => {
  let str = '未填写'
  if (form.target || form.filename) {
    str = toLinuxPath(form.target + '/' + form.filename)
  }
  return `上传路径（上传到服务器的完整路径：${str}）`
})

defineExpose({open})
</script>

<template>
  <el-dialog v-model="dialogVisible" :title="form.id ? form.title : 'Server端新增'" style="max-width: 1000px"
             width="90%" top="10px"
             :close-on-click-modal="false">
    <el-scrollbar class="el-dialog-scrollbar">
      <el-form ref="formRef" :model="form" label-position="top">
        <el-form-item label="快捷新增（从已录入的数据复制过来简单修改）" v-if="serverStorage.length">
          <el-dropdown ref="dropdownRef" trigger="click" placement="bottom-start">
            <el-button type="primary">
              从已录入的数据-新增
              <el-icon class="ml5">
                <ArrowDown/>
              </el-icon>
            </el-button>
            <template #dropdown>
              <el-tree :data="serverStorage" node-key="id" default-expand-all :props="{label: 'title'}"
                       style="height: 250px"
                       placeholder="请选择一个配置复制" class="pa10" @node-click="onCommand">
                <template #default="{ data }">
                  <span>{{ data.title }}</span>
                  <span v-if="data.filename">（{{ data.filename }}）</span>
                </template>
              </el-tree>
            </template>
          </el-dropdown>
        </el-form-item>
        <el-form-item label="标题" prop="title">
          <el-input v-model="form.title" autocomplete="off" placeholder="请输入标题" clearable/>
        </el-form-item>
        <el-form-item label="服务器" prop="ftp_id">
          <el-tree-select :data="ftpStorage" node-key="id" default-expand-all clearable
                          v-model="form.ftp_id" :props="{label: 'title'}"
                          placeholder="请选择上传服务器">
            <template #default="{ data }">
              <span>{{ data.title }}</span>
              <span v-if="data.host">（{{ data.host }} - {{ data.system }}）</span>
            </template>
          </el-tree-select>
        </el-form-item>
        <el-form-item label="文件名（不填默认使用上传路径/最后一个名称）" prop="filename">
          <el-input v-model="form.filename" autocomplete="off" placeholder="请输入文件名" clearable/>
        </el-form-item>
        <el-form-item :label="targetLabel" prop="target">
          <el-input v-model="form.target" autocomplete="off" placeholder="请输入上传路径" clearable/>
        </el-form-item>
        <el-form-item label="本地路径（会上传这个路径下的文件（不含排除）例：D:\Project\www）" prop="source">
          <el-input v-model="form.source" autocomplete="off" placeholder="请输入本地路径" clearable/>
        </el-form-item>
        <el-form-item prop="exclude">
          <el-card style="width: 100%" shadow="never">
            <template #header>
              <div class="card-header flex align-center justify-between">
                <span>排除的文件或文件夹</span>
                <div class="flex align-center">
                  <el-input v-model="filename" placeholder="文件夹或文件名(带后缀)" style="width: 150px"/>
                  <el-button @click="exportAddExclude" class="ml5">导入默认排除文件</el-button>
                  <el-button type="primary" @click="onAddExclude" class="ml5">新增排除文件/文件夹</el-button>
                </div>
              </div>
            </template>
            <ul class="list" v-if="form.exclude.length">
              <li class="list-item e-border flex align-center justify-between" v-for="(item, index) in form.exclude"
                  :key="index">
                <span>{{ item }}</span>
                <el-icon @click="onRemoveExclude(index)" color="red" class="cursor-pointer icon">
                  <Close/>
                </el-icon>
              </li>
            </ul>
            <el-empty v-else :image-size="30" style="padding: 0"/>
          </el-card>
        </el-form-item>
        <el-form-item label="需要重启的IIS网站名称（默认使用文件名）" prop="appcmd" v-if="ftp?.system === 'window'">
          <el-input v-model="form.appcmd" autocomplete="off" placeholder="默认使用文件名" clearable/>
        </el-form-item>
        <el-form-item prop="writes">
          <el-card style="width: 100%" shadow="never">
            <template #header>
              <div class="card-header flex align-center justify-between">
                <span>上传结束后执行的命令行</span>
                <div class="flex align-center">
                  <el-input v-model="write" placeholder="请输入命令行" style="width: 180px"/>
                  <!--                  <div class="ml5" v-if="ftp?.system === 'window'">-->
                  <!--                    <el-button @click="onWriteCmd('iisreset /start')">IIS全部服务启动</el-button>-->
                  <!--                    <el-button @click="onWriteCmd('iisreset /stop')">IIS全部服务停止</el-button>-->
                  <!--                  </div>-->
                  <div class="ml5" v-if="ftp?.system === 'linux'">
                    <el-button @click="onWriteCmd('systemctl restart ')">Linux重启前缀</el-button>
                  </div>
                  <el-button type="primary" @click="onAddWrite" class="ml5">新增命令行</el-button>
                </div>
              </div>
            </template>
            <ul class="list" v-if="form.writes.length">
              <li class="list-item e-border flex align-center justify-between" v-for="(item, index) in form.writes"
                  :key="index">
                <span>{{ item }}</span>
                <el-icon @click="onRemoveWrite(index)" color="red" class="cursor-pointer icon">
                  <Close/>
                </el-icon>
              </li>
            </ul>
            <el-empty v-else :image-size="30" style="padding: 0"/>
          </el-card>
        </el-form-item>
      </el-form>
    </el-scrollbar>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="dialogVisible = false" :icon="Close">取消</el-button>
        <el-button type="primary" @click="onSubmitForm" :icon="Check">
          确认
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>
<style scoped>
.list {
  list-style: none;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
}

.list .list-item {
  padding: 0 5px;
  margin-right: 6px;
}

.list .list-item .icon {
  width: 30px;
  text-align: right;
}
</style>
